package com.apotik.legenda.frameinternal;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;

import com.apotik.legenda.custom.TableModelCustom;
import com.apotik.legenda.dao.SupplierDao;
import com.apotik.legenda.dialog.AddEditSupplierDialog;
import com.apotik.legenda.model.Supplier;
import com.apotik.legenda.model.User;
import com.apotik.legenda.observer.GeneralObserver;
import com.apotik.legenda.util.CalendarUtil;

import java.awt.Font;

public class SupplierInternalFrame extends JInternalFrame implements ActionListener, GeneralObserver  {
	private static final long serialVersionUID = 1L;
	

	private JButton btnAdd;
	private JButton btnEdit;
	private JButton btnDelete;
	private JButton btnRefresh;
	
	private JButton btnBackPage;
	private JButton btnNextPage;
	private JLabel lblKetData = new JLabel();
	private JTextField textFieldSearch;
	
	private TableModelCustom tableModel;
	private JTable table;
	private AddEditSupplierDialog addEditSupplierDialog;
	
	private User user;
	private int modelRow  = -1;
	private int maxData = 50;
	private int sizePage = 0;
	private int activePageIndex = 0;
	private String[] columnNames = {"No.", "Nama", "Kode", "Tanngal Dibuat ", "Dibuat oleh"};
	
	@SuppressWarnings("rawtypes")
	private Vector vectorRow;
	
	@SuppressWarnings("serial")
	public SupplierInternalFrame(User user) {
		super("Supplier", true, true, true, true);
		setSize(800, 400);
		setVisible(true);
		
		this.user = user;
		
		JPanel northPanel = new JPanel();
		northPanel.setLayout(new BorderLayout());
		getContentPane().add(northPanel, BorderLayout.NORTH);
		
		JPanel headPanel = new JPanel();
		headPanel.setLayout(new BorderLayout());
		northPanel.add(headPanel, BorderLayout.NORTH);
		
		JPanel btns1Panel = new JPanel();
		btns1Panel.setLayout(new FlowLayout());
		headPanel.add(btns1Panel, BorderLayout.WEST);
		
		btnAdd = new JButton("Tambah");
		btnAdd.addActionListener(this);
		btnAdd.setMnemonic(KeyEvent.VK_N);
		btnAdd.setToolTipText("ALT + N");
		btns1Panel.add(btnAdd);
		
		btnEdit = new JButton("Edit");
		btnEdit.addActionListener(this);
		btns1Panel.add(btnEdit);
		
		btnDelete = new JButton("Delete");
		btnDelete.addActionListener(this);
		btns1Panel.add(btnDelete);
		
		btnRefresh = new JButton("Refresh");
		btnRefresh.addActionListener(this);
		btns1Panel.add(btnRefresh);
		
		textFieldSearch = new JTextField();
		textFieldSearch.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
		        if (e.getKeyCode()==KeyEvent.VK_ENTER){
		        	String search = textFieldSearch.getText().trim();
		        	loadDataTable(0, search);
		        	
		        	int totalData = totalData();
		        	int _maxData = maxData;
		        	if(totalData<maxData){
		        		_maxData = totalData;
		        	}
		        	lblKetData.setText("   Data 1-"+_maxData+" dari "+totalData);
		        }
			}
			@Override
			public void keyTyped(KeyEvent arg0) {
			}
		});
		headPanel.add(textFieldSearch, BorderLayout.EAST);
		textFieldSearch.setColumns(25);
		
		JLabel lblCari = new JLabel("Cari Nama/Kode: ");
		lblCari.setHorizontalAlignment(SwingConstants.RIGHT);
		headPanel.add(lblCari, BorderLayout.CENTER);
		
		JSeparator separator = new JSeparator();
		northPanel.add(separator, BorderLayout.SOUTH);
		
		JScrollPane scrollPane = new JScrollPane();
		getContentPane().add(scrollPane, BorderLayout.CENTER);
		
		tableModel = new TableModelCustom(columnNames);
		loadDataTable(0, "");
		
		table = new JTable(){
			@Override
			public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
				JLabel label = (JLabel) super.prepareRenderer(renderer, row, column);
				
				if(column==0 || column==3){
					label.setHorizontalAlignment(JLabel.CENTER);
				}/*else if(column==7 || column==8){
					label.setHorizontalAlignment(JLabel.RIGHT);
				}*/else{
					label.setHorizontalAlignment(JLabel.LEFT);
				}
				
				return label;
			}
		};
		table.setModel(tableModel);
		table.setEnabled(true);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				int viewRow = table.getSelectedRow();
				if(viewRow>-1){
					modelRow = table.convertRowIndexToModel(viewRow);
				}
			}
		});
		scrollPane.setViewportView(table);
		
		String actionMapStr = "selected_row";
		table.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), actionMapStr);
		table.getActionMap().put(actionMapStr, new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				Supplier s = selectedModel();
				System.out.println("Name: "+s.getSupplierName());
			}
		});
		
		JPanel panel = southPanel();
		getContentPane().add(panel, BorderLayout.SOUTH);
	}
	
	private JPanel southPanel(){
		JPanel southPanel = new JPanel();
		southPanel.setLayout(new BorderLayout(0, 0));
		
		JPanel panel_1 = new JPanel();
		southPanel.add(panel_1, BorderLayout.EAST);
		
		btnBackPage = new JButton("< Back");
		btnBackPage.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnBackPage.addActionListener(this);
		panel_1.add(btnBackPage);
		
		btnNextPage = new JButton("Next >");
		btnNextPage.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnNextPage.addActionListener(this);
		panel_1.add(btnNextPage);
		
		southPanel.add(lblKetData, BorderLayout.WEST);
				
		return southPanel;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void loadDataTable(int start, String searchValue){
		SupplierDao dao = new SupplierDao();
		List<Supplier> list = new ArrayList<>();
		if(searchValue.equalsIgnoreCase("")){
			list = dao.listByAnyCriteria(true, "", start, maxData);
		}else{
			list = dao.listByAnyCriteria(true, searchValue, start, maxData);
		}
		
		deleteAllTableRow();
		if(list!=null){
			int size = list.size();
			if(size>0){
				int i = start+1;
				for(Supplier o: list){
					Vector v = new Vector();
					v.add(i);
					v.add(o.getSupplierName());
					v.add(o.getSupplierCode());
					v.add(o.getCreatedDate()!=null ? CalendarUtil.formatDate(o.getCreatedDate(), "d-MMM-YYYY"):"");
					v.add(o.getCreatedBy().getFullName());
					v.add(o);
					tableModel.insertData(v);
					i++;
				}
				
				int _totalData = totalData();
				if(_totalData<maxData){
					lblKetData.setText("   Data "+(start+1)+" - "+_totalData+" dari "+_totalData);
				}else{
					lblKetData.setText("   Data "+(start+1)+" - "+(start+maxData)+" dari "+_totalData);
				}
			}else{
				lblKetData.setText("   Data 0 dari 0");
			}
		}   
	}
	
	private int totalData(){
		String searchValue = textFieldSearch.getText().trim();
		
		SupplierDao dao = new SupplierDao();
		int sizeData = dao.size(true, true, searchValue);
		return sizeData;
	}
	
	private String[] paginationValues(){
		int sizeRow = totalData();
		int divide = sizeRow/maxData;
		int mod = sizeRow % maxData;
		sizePage = divide;
		if(mod!=0){
			sizePage = divide + 1;
		}
		
		String[] result = new String[sizePage];
		for(int i=0;i<sizePage;i++){
			result[i] = Integer.toString(i+1);
		}
		return result;
	}
	
	@SuppressWarnings("rawtypes")
	private Supplier selectedModel(){
		Supplier obj = null;
		if(modelRow!=-1){
			Vector v = (Vector) tableModel.getRowVector().get(modelRow);
			if(v!=null){
				obj = (Supplier) v.get(v.size()-1);
				vectorRow = v;
			}
		}
		return obj;
	}
	
	private void addNew(){
		boolean isVisible = false;
		if(addEditSupplierDialog!=null){
			isVisible = addEditSupplierDialog.isVisible();
		}
		
		if(isVisible){
			addEditSupplierDialog.toFront();
			addEditSupplierDialog.requestFocus();
		}else{
			addEditSupplierDialog = new AddEditSupplierDialog("Tambah Supplier", user, this);
			addEditSupplierDialog.setVisible(true);
			addEditSupplierDialog.requestFocus();
		}
	}
	
	private void editItem(){
		Supplier p = selectedModel();
		if(p!=null){
			boolean isVisible = false;
			if(addEditSupplierDialog!=null){
				isVisible = addEditSupplierDialog.isVisible();
			}
			
			if(isVisible){
				addEditSupplierDialog.toFront();
				addEditSupplierDialog.requestFocus();
			}else{
				addEditSupplierDialog = new AddEditSupplierDialog("Edi Supplier", user, this);
				addEditSupplierDialog.setVisible(true);
				addEditSupplierDialog.requestFocus();
				addEditSupplierDialog.fillInTheFields(vectorRow, activePageIndex);
			}
		}else{
			JOptionPane.showMessageDialog(null, "Silahkan Pilih Row Table", "Exception", JOptionPane.ERROR_MESSAGE);
		}
		
	}
	
	private void deleteItem(){
		if(selectedModel()!=null){
			int result = JOptionPane.showConfirmDialog(null, "Apakah Anda yakin ingin menghapusnya?", "Question", JOptionPane.YES_NO_OPTION);
			if(result==JOptionPane.YES_OPTION){
				SupplierDao dao = new SupplierDao();
				boolean isSucces = dao.inactive(selectedModel());
				if(isSucces){
					//tableModel.removeRow(modelRow);
					
					int start = 0;
					if(activePageIndex==-1){//kalo insert
						start = (paginationValues().length-1) * maxData;
					}else{
						start = activePageIndex * maxData;
					}
					
					loadDataTable(start, textFieldSearch.getText().trim());
					
					int totalData = totalData();
					lblKetData.setText("   Data "+(start+1)+" - "+totalData+" dari "+totalData);
				}
			}
		}else{
			JOptionPane.showMessageDialog(null, "Silahkan Pilih Row Table", "Exception", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	private void deleteAllTableRow(){
		tableModel.removeRowAll();
	}

	
	@Override
	public void actionPerformed(ActionEvent ae) {
		Object obj =  ae.getSource();
		
		if(obj==btnAdd){
			addNew();
		}else if(obj==btnEdit){
			editItem();
		}else if(obj==btnDelete){
			deleteItem();
		}else if(obj==btnRefresh){
			deleteAllTableRow();
			loadDataTable(0, "");
			activePageIndex = 0;
		}else if(obj==btnBackPage){
			if(activePageIndex!=0){
				int minusOne = activePageIndex-1;
				
				int start = 0;
				String[] paginContent = paginationValues();
				for(int i=0;i<paginContent.length;i++){
					if(i==minusOne){
						start = i*maxData;
					}
				}
				
				activePageIndex = minusOne;
				loadDataTable(start, textFieldSearch.getText().trim());
			}
		}else if(obj==btnNextPage){
			int plusOne = activePageIndex+1;
			if((plusOne)!=sizePage){
				int start = 0;
				String[] paginContent = paginationValues();
				for(int i=0;i<paginContent.length;i++){
					if(i==plusOne){
						start = i*maxData;
					}
				}
				
				activePageIndex = plusOne;
				loadDataTable(start, textFieldSearch.getText().trim());
				
				/*System.out.println("sizePage: "+sizePage);
				System.out.println("plusOne: "+plusOne);
				System.out.println();*/
				
				int _totalData = totalData();
				if(sizePage==(plusOne+1)){
					lblKetData.setText("   Data "+(start+1)+" - "+_totalData+" dari "+_totalData);
				}else{
					if(_totalData<maxData){
						lblKetData.setText("   Data "+(start+1)+" - "+_totalData+" dari "+_totalData);
					}else{
						lblKetData.setText("   Data "+(start+1)+" - "+(start+maxData)+" dari "+_totalData);
					}
				}
			}
		}
	}
	
	@Override
	public void response(HashMap<String, Object> hm) {
		try {
			int activePageIndex = (int) hm.get("activePageIndex");
			
			int start = 0;
			if(activePageIndex==-1){//kalo insert
				start = (paginationValues().length-1) * maxData;
			}else{
				start = activePageIndex * maxData;
			}

			loadDataTable(start, textFieldSearch.getText().trim());
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}